<?php
/**
 * Payment.php 支付记录类
 *
 * @author camfee <camfee@foxmail.com>
 * @date   17-8-31 下午5:44
 *
 */

namespace Center;

use Common\Bridge;
use Common\ModuleBase;

class Payment extends ModuleBase
{
    /**
     * 支付类型, 1 微信 3 支付宝 3 appstore
     */
    const PAY_TYPE_APP_STORE = 0;
    const PAY_TYPE_WEIXIN = 1;
    const PAY_TYPE_QPAY = 2;
    const PAY_TYPE_ALIPAY = 3;
    // 状态: 0 等待支付, 1 支付中，2 支付成功，3 支付失败，4 取消支付 5:发货失败
    const STATUS_WAIT_PAY = 0;
    const STATUS_PAYING = 1;
    const STATUS_PAY_SUCCESS = 2;
    const STATUS_PAY_FAILURE = 3;
    const STATUS_PAY_CANCELED = 4;
    const STATUS_SEND_GOODS_FAILED = 5;

    protected static $_conf = [
        'db' => [
            'w' => Bridge::DB_CENTER_W,
            'r' => Bridge::DB_CENTER_R
        ],
        'table' => 'Payment',
        'fields' => [
            'PaymentId' => self::VAR_TYPE_KEY,
            'UserId' => self::VAR_TYPE_INT,
            'SN' => self::VAR_TYPE_STRING,
            'ProductId' => self::VAR_TYPE_STRING,
            'AppId' => self::VAR_TYPE_INT,
            'DeviceId' => self::VAR_TYPE_STRING,
            'GoodsInfo' => self::VAR_TYPE_STRING,
            'PaymentType' => self::VAR_TYPE_STRING,
            'TradeNo' => self::VAR_TYPE_STRING,
            'TotalFee' => self::VAR_TYPE_STRING,
            'ThirdSN' => self::VAR_TYPE_STRING,
            'Content' => self::VAR_TYPE_JSON,
            'Status' => self::VAR_TYPE_INT,
            'UpdateTime' => self::VAR_TYPE_STRING,
            'CreateTime' => self::VAR_TYPE_STRING,
        ],
        'mc' => '',
        'mckey' => '',
        'mctime' => 86400
    ];

    static protected $_add_must_fields = [
        'AppId' => 1,
        'DeviceId' => 1,
        'UserId' => 1,
        'GoodsInfo' => 1,
        'SN' => 1,
        'ProductId' => 1,
        'PaymentType' => 1,
        'TotalFee' => 1,
    ];

    /**
     * @see ModuleBase::add() 新增
     * @see ModuleBase::update() 更新
     * @see ModuleBase::getInfoByIds() 按id查询
     * @see ModuleBase::getList() 条件查询
     * @see ModuleBase::delete() 删除
     */

    /**
     * 是否首次充值
     *
     * @param $uid
     * @return bool
     */
    public static function isFirstPay($uid)
    {
        return self::checkPaymentCount($uid) < 1 ? true : false;
    }

    /**
     * 获取用户支付成功的次数
     *
     * @param $uid
     * @return null
     */
    public static function checkPaymentCount($uid)
    {
        $where = [
            'UserId' => $uid,
            'Status' => self::STATUS_PAY_SUCCESS
        ];
        $count = self::getPdo()->select('count(*)')->from('Payment')->where($where)->getValue();

        return $count;
    }

    /**
     * @param string $sn   支付流水号
     * @param array  $info 更新数组
     * @return int 0 成功，1 包含不可修改字段，2 数据库更新失败, 3 sn找不到
     */
    public static function updatePaymentBySN($sn, $info)
    {
        $payment_info = self::getInfoBySN($sn);
        if (empty($payment_info['PaymentId'])) {
            debug_log("payment not found in db, sn: {$sn}");

            return false;
        }

        return self::update($payment_info['PaymentId'], $info);
    }

    /**
     * 支付成功
     *
     * @param string $sn 订单流水号
     * @param        $info
     * @return int
     */
    public static function paySuccess($sn, $info)
    {
        $payment_info = self::getInfoBySN($sn);
        if (empty($payment_info['PaymentId'])) {
            debug_log(['payment not found in db', $sn]);

            return false;
        }
        $ret = self::update($payment_info['PaymentId'], $info);

        return $ret;
    }

    /**
     * 由sn获取
     *
     * @param $sn
     * @return array|mixed
     */
    public static function getInfoBySN($sn)
    {
        $where = [
            'SN' => $sn
        ];
        $extra = [
            'offset' => 0,
            'limit' => 1,
            'fields' => '*',
        ];

        $ret = parent::getDataByFields($where, $extra);

        return !empty($ret['data']) ? current($ret['data']) : [];
    }

    /**
     * 由第三方sn获取
     *
     * @param $third_sn
     * @param $pay_type
     * @return array|mixed
     */
    public static function getInfoByThirdSN($third_sn, $pay_type)
    {
        $where = [
            'ThirdSN' => $third_sn,
            'PaymentType' => $pay_type
        ];
        $extra = [
            'offset' => 0,
            'limit' => 1,
            'fields' => '*',
        ];

        $ret = parent::getDataByFields($where, $extra);

        return !empty($ret['data']) ? current($ret['data']) : [];
    }

    /**
     * 生成支付流水号, appid(2) + $pay_type(1) + channel(6) + yymmddHHMMSSssssss(18) + rand_number
     *
     * @param int    $app_id   应用id
     * @param string $pay_type 支付类型
     * @param string $channel  渠道号
     * @return string
     */
    public static function generateSN($app_id, $pay_type, $channel)
    {
        if (strlen($channel) > 6) {
            $channel = substr($channel, 0, 6);
        }
        $us_str = sprintf('%f', microtime(true));
        $arr = explode('.', $us_str);
        $sn = sprintf("%d%d%s%s%d", $app_id, $pay_type, $channel, date('ymdHis'), $arr[1]);
        $l = 32 - strlen($sn);
        if ($l > 0) {
            $num = rand(pow(10, $l - 1), pow(10, $l) - 1);
            $sn .= sprintf('%d', $num);
        }

        return $sn;
    }
}